package gee

import (
	"fmt"
	"log"
	"net/http"
)

// HandlerFunc defines the request handler used by gee
type HandlerFunc func(http.ResponseWriter, *http.Request)

// Engine is the uni handler for all requests
type Engine struct {
	router map[string]HandlerFunc
}

// Engine 构造函数
func New() *Engine {
	return &Engine{
		router: make(map[string]HandlerFunc),
	}
}

func (engine *Engine) addRoute(method, path string, handler HandlerFunc) {
	assert(path[0] == '/', "path must begin")
	assert(method != "", "method must not be empty")
	key := method + "-" + path
	log.Printf("Route %4s - %s", method, path)
	engine.router[key] = handler
}
func (engine *Engine) GET(relativePath string, handlerFunc HandlerFunc) {
	engine.addRoute(http.MethodGet, relativePath, handlerFunc)
}

func (engine *Engine) POST(relativePath string, handlerFunc HandlerFunc) {
	engine.addRoute(http.MethodPost, relativePath, handlerFunc)
}

func (engine *Engine) PUT(relativePath string, handlerFunc HandlerFunc) {
	engine.addRoute(http.MethodPut, relativePath, handlerFunc)
}
func (engine *Engine) DELETE(relativePath string, handlerFunc HandlerFunc) {
	engine.addRoute(http.MethodDelete, relativePath, handlerFunc)
}
func (engine *Engine) Run(addr string) (err error) {
	fmt.Sprintf("[GIN-debug] Listening and serving HTTP on %s\n", addr)
	err = http.ListenAndServe(addr, engine)
	return
}

func assert(guard bool, text string) {
	if !guard {
		panic(text)
	}
}

// 实现ServeHTTP方法后，拦截了所有的http请求，拥有了统一的控制入口
// 在这里一般实现自定义路由以及统一添加一些逻辑处理：如日志，异常处理等
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	key := req.Method + "-" + req.URL.Path

	if handler, ok := engine.router[key]; ok {
		handler(w, req)
	} else {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, "404 NOT FOUND: %s\n", req.URL)
	}
}
